﻿#ifndef _tcp_server_impl_20220407_
#define _tcp_server_impl_20220407_


#include <thread>
#include <map>
#include <list>
#include <mutex>
#include "SL_asynFramePub.h"

#include "SL_tcpClient_impl.h"
#include "SL_tcpClient.h"
#include "SL_tcpServer.h"

struct _tcp_event_info
{
	int m_cmd = -1;
	int m_socket = -1;
	int m_port = 0;
	SLTcpClientEpollImplPtr m_clientPtr;
};

class SLTcpServerEpollImpl : public SLTcpServer
{
	struct _tcp_listen_info
	{
		int m_listenSocket = -1;
		int m_ip = 0;
		int m_port = 0;
	};
public:

	SLTcpServerEpollImpl();

	virtual int init(SLTcpServerCB* pcb);
	virtual void uninit() {}
	virtual void start();
	virtual void stop() {}
	virtual int addListen(std::string _ip, int _port);
	virtual int delListen(std::string _ip, int _port) {return -1;}
	virtual SLTcpClientPtr   createClient();

public:
	void postEvent(_tcp_event_info& _ev);
	void postEvent2(uint32_t cmd, uint32_t fd);
	void checkTimeOut();
private:
	int HandlingEvent(int eventFd);
	void HandlingEventList();

	void EpollDel(int nSocket);
	void EpollMod(int nSocket, struct epoll_event* ev);
	void EpollAdd(int nSocket, struct epoll_event* ev);
	int  NetAcceptSocket(int socket, int& _rip, int& _rport);
private:
	void thread_listen(void);
	int recvConnect(_tcp_listen_info& _listenInfo);

	int NetMakeSocket(int port);
	int AnetKeepAlive(int fd);
	void NetClose(int socket);

	//int m_Sersocket = 0;
	std::map<int, _tcp_listen_info>  m_listenMap; //key为监听socket
	std::map<int, SLTcpClientEpollImplPtr>    m_clientMap; //key 数据socket

	std::mutex    m_eventInfoListLock;
	std::list< _tcp_event_info>  m_eventInfoList;

	std::thread   m_thread;

	SLTcpServerCB* m_pcb = nullptr;
	int  m_epoll_fd = -1;
	int m_QuitEventfd = -1;

	std::atomic< uint32_t>   m_clientIDBase{1};

	//accept 失败后需要主动重试
	int  m_accpetTimeout = -1;
	std::list<_tcp_listen_info>  m_accpentList;
};

typedef std::shared_ptr<SLTcpServerEpollImpl> SLTcpServerEpollImplSPtr;

//tcpclent 超时回收检测
class SLTcpTimeoutCheckSession : public SLF_SessionBase
{
public:
	virtual void OnStart();
	virtual void OnStop() {}
	virtual void OnMsgArrive(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data) {}
	virtual void OnTimer(uint32_t timerID, int _intervalMs, bool periodic);

	SLTcpServerEpollImpl* m_ptcpServer = nullptr;
};

#endif